﻿// 1016train01.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;

int partition(vector<int>& num_v, int low, int high)
{
	int privot = num_v[low];
	int i = low;
	for (int j=i+1; j<(int)num_v.size(); j++)
	{
		if (num_v[j]<privot)
		{
			i++;
			swap(num_v[j], num_v[i]);
		}
	}
	swap(num_v[i], num_v[low]);
	return i;
	//
}

void quickSort(vector<int>&num_v, int low ,int high)
{
	if (low<high)
	{
		int privot_pos = partition(num_v, low, high);
		quickSort(num_v, low, privot_pos - 1);
		quickSort(num_v, privot_pos + 1, high);
		//
	}
	//
}

class Solution01
{
public:
	Solution01(vector<vector<int>>&grid, vector<int>&sort_para,int row_size,int col_size)
	{
		sort(grid.begin(), grid.end(), [&](vector<int>& vec_a, vector<int>& vec_b)
			{
				bool result = true;
				for (int k = 0; k < col_size; k++)
				{
					//1降序 -1升序
					if (vec_a[k] == vec_b[k]) continue;
					if (sort_para[k] == 1)
					{
						result = vec_a[k] > vec_b[k];
						return result;
					}
					if (sort_para[k] == -1)
					{
						result = vec_a[k] < vec_b[k];
						return result;
					}
				}
				return result;
			});

		for (int r=0; r<row_size; r++)
		{
			vector<int>curr = grid[r];
			for (int c=0; c<col_size; c++)
			{
				cout << curr[c];
				if (c!=col_size-1)
				{
					cout << ' ';
				}
			}
			if (r!=row_size-1)
			{
				cout << '\n';
			}
		}

		//
	}
};


class Solution02
{
public:
	bool isCharacter(char ch)
	{
		return ch >= 'A' && ch <= 'Z';
		//
	}

	vector<int>getRowCol(string& str)
	{
		int col = str[0] - 'A';
		int row = str[1] - '0' - 1;

		return { row, col };
		//
	}

	int computeStr(vector<vector<string>>& grid, string&str)
	{
		bool need_compute = false;
		for (int i=0; i<(int)str.size(); i++)
		{
			if (isCharacter(str[i]))
			{
				need_compute = true;
				break;
			}
		}
		if (!need_compute) return stoi(str);

		vector<int>row_col = getRowCol(str);
		return getVal(grid, row_col[0], row_col[1]);
		
	}

	int getVal(vector<vector<string>>& grid, int row, int col)
	{
		string curr = grid[row][col];
		if (curr.find('=') == string::npos) return stoi(curr);

		//去掉等号
		curr = curr.substr(1);

		int sign = 0, sign_index = -1;
		if (curr.find('+') != string::npos)
		{
			sign = 1;
			sign_index = (int)curr.find('+');
		}
		if (curr.find('-') != string::npos)
		{
			sign = -1;
			sign_index = (int)curr.find('-');
		}
		

		if (sign == 0)
		{
			vector<int>row_col = getRowCol(curr);
			int curr_val = getVal(grid, row_col[0], row_col[1]);
			return curr_val;
		}

		vector<string>str_vec(2);

		str_vec[0] = curr.substr(0, sign_index);
		str_vec[1] = curr.substr(sign_index + 1);

		vector<int>val_vec(2);

		val_vec[0] = computeStr(grid, str_vec[0]);
		val_vec[1] = computeStr(grid, str_vec[1]);
		
		return val_vec[0] + sign * val_vec[1];
		//
	}

	void getComputeArea(string& compute_str)
	{
		int split_index = compute_str.find(':');

		string start_str = compute_str.substr(0, split_index);
		start_v = getRowCol(start_str);

		string end_str = compute_str.substr(split_index + 1);
		end_v = getRowCol(end_str);

		//
	}

	Solution02(
		vector<vector<string>>& grid,
		string& compute_str,
		int row_size,
		int col_size
	)
	{
		real_grid = vector<vector<long long>>(row_size, vector<long long>(col_size));

		getComputeArea(compute_str);

		for (int r=0; r<row_size; r++)
		{
			for (int c=0; c<col_size; c++)
			{
				real_grid[r][c] = getVal(grid, r, c);
			}
		}

		long long result = 0;
		for (int r=start_v[0]; r<= end_v[0]; r++)
		{
			for (int c= start_v[1]; c<=end_v[1]; c++)
			{
				result += real_grid[r][c];
			}
		}

		cout << result;
		//
	}
private:
	vector<vector<long long>>real_grid;
	vector<int>start_v, end_v;
};


int main()
{
	{
/*
5 3
10 12 =C5
15 5 6
7 8 =3+C2
6 =B2-A1 =C2
7 5 3
B2:C4
*/

		int row_size, col_size;
		cin >> row_size >> col_size;

		vector<vector<string>>grid(row_size, vector<string>(col_size));

		for (int r=0; r<row_size; r++)
		{
			for (int c=0; c<col_size; c++)
			{
				cin >> grid[r][c];
			}
		}

		string compute_str;
		cin >> compute_str;

		Solution02 solu(grid, compute_str, row_size, col_size);

		return 0;
	}
	{
/*
4 3
1 -1 1
2 2 2
2 3 3
4 4 4
4 4 5
*/
		int row_size, col_size;
		cin >> row_size >> col_size;

		vector<int>sort_para(col_size);
		for (int i=0; i<col_size; i++)
		{
			cin >> sort_para[i];
		}

		vector<vector<int>>grid(row_size, vector<int>(col_size));

		for (int r=0; r<row_size; r++)
		{
			for (int c=0; c<col_size; c++)
			{
				cin >> grid[r][c];
			}
		}
		Solution01 solu(grid, sort_para, row_size, col_size);

		return 0;
	}

	vector<int>num_v = { 10, 7, 8, 9, 1, 5 };
	quickSort(num_v, 0, int(num_v.size()));
	for (auto&num:num_v)
	{
		cout << num << ' ';
	}

}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
